//
//  ViewController.m
//  OC_Principle
//
//  Created by wangzhipan on 2025/2/5.
//

#import "ViewController.h"
#import "ZYStudent.h"
#import "ZYPerson.h"
#import <malloc/malloc.h>
#import <objc/runtime.h>
#import "ZYRuntime.h"
#import "ZYForwardingMsg.h"
#import "ZYRunloopObserver.h"
#import "ZYActiveThread.h"
#import "NSGCDGroup.h"
#import "ZYConditionLockTest.h"
#import "ZYRWLock.h"
#import "ZYGcdBarrierTest.h"
#import "ZYTimerTest.h"
#import "arm.h"
#import "ZYGCDTimer.h"
#import "ZYTestView.h"

@interface ViewController ()
@property (nonatomic, strong, nullable) ZYRunloopObserver *observer;


@property (nonatomic, strong) dispatch_source_t timer;
@end

@implementation ViewController

- (void)test01
{
    /*
     查看对象所占内存空间，涉及两个函数：
     class_getInstanceSize：只能查看对象在内存对齐后，所占内存空间大小【注意，内存对齐要是最大的那个变量所占字节数的倍数】
     malloc_size：是runtime实际分配的内存大小，oc源码中，最小分配16个字节，然后所分配的内存必须是16的倍数
     */
    ZYStudent *st = [[ZYStudent alloc] init];
    st.age = 20;
    st.height = 183;
    
    NSLog(@"%lu, %zu", class_getInstanceSize([ZYStudent class]), malloc_size((__bridge void *)st));
}


struct zy_objc_class {
    Class isa;
    Class superClass;
};
- (void)test02
{
    /*
     实例对象、类对象、metaClass:
     
      1.Class objc_getClass(const char *aClassName)
      1> 传入字符串类名
      2> 返回对应的类对象
      
      2.Class object_getClass(id obj)
      1> 传入的obj可能是instance对象、class对象、meta-class对象
      2> 返回值
      a) 如果是instance对象，返回class对象
      b) 如果是class对象，返回meta-class对象
      c) 如果是meta-class对象，返回NSObject（基类）的meta-class对象
      
      3.- (Class)class、+ (Class)class
      1> 返回的就是类对象
      
      - (Class) {
          return self->isa;
      }
      
      + (Class) {
          return self;
      }
     */
    ZYStudent *st = [ZYStudent new];  //实例对象
    
    Class class_obj = [ZYStudent class];  //类对象
    
    Class meta_obj = object_getClass(class_obj);  //元类对象
    
    Class meta_obj1 = objc_getMetaClass("ZYStudent");
    Class meta_person = objc_getMetaClass("ZYPerson");
    NSLog(@"%p\n%p\n%p\n%p\nperson_metaCls=%p\n", st, class_obj, meta_obj, meta_obj1, meta_person);
    
    unsigned int class_count = 0;
    Method *class_methods = class_copyMethodList(class_obj, &class_count);
    
    NSLog(@"-------------------类对象的方法----------------------------:\n");
    
    for (int i = 0; i < class_count; i++) {
        Method md = class_methods[i];
        SEL sel = method_getName(md);
        const char *type = method_getTypeEncoding(md);
        NSLog(@"name:%s,  type:%s\n", sel, type);
    }
    free(class_methods);
    
    NSLog(@"\n\n-------------------类对象的superClass----------------------------:\n");
    NSLog(@"currentClass==%s", object_getClassName(class_obj));
    Class tmpCls = class_getSuperclass(class_obj);
    while (tmpCls) {
        NSLog(@"%s", object_getClassName(tmpCls));
        tmpCls = class_getSuperclass(tmpCls);
    }
    
    
    NSLog(@"\n\n-------------------元类对象的方法----------------------------:\n");
    unsigned int meta_count = 0;
    Method *meta_methods = class_copyMethodList(meta_obj, &meta_count);
    for (int i = 0; i < meta_count; i++) {
        Method md = meta_methods[i];
        SEL sel = method_getName(md);
        const char *type = method_getTypeEncoding(md);
        NSLog(@"name:%s,  type:%s\n", sel, type);
    }
    free(meta_methods);
    
    
    NSLog(@"\n\n-------------------元类对象的superClass----------------------------:\n");
    NSLog(@"currentClass==%@", ((__bridge struct zy_objc_class *)meta_obj)->superClass);
    tmpCls = class_getSuperclass(meta_obj);
    while (tmpCls) {
        NSLog(@"%p == %@", tmpCls, ((__bridge struct zy_objc_class *)tmpCls)->superClass);
        tmpCls = class_getSuperclass(tmpCls);
    }
}
- (IBAction)clickBtn:(id)sender 
{
    NSLog(@"%s", __func__);
}

- (void)test_runtime
{
    /*动态消息解析
    ZYRuntime *runtime = [ZYRuntime new];
    [runtime run];
    [ZYRuntime setId:10];
     */
    
    //消息转发、崩溃防护
    ZYForwardingMsg *msg = [ZYForwardingMsg new];
    [msg run];
    [ZYForwardingMsg doSomething];
}

- (void)test_runloop
{
    //observer监听runloop各种状态
    ZYRunloopObserver *observer = [ZYRunloopObserver new];
    [observer observeMainRunLoop];
    self.observer = observer;
        
    {
        //runloop 线程保活封装
        ZYActiveThread *thread = [[ZYActiveThread alloc] init];
        [thread executeTask:^{
            NSLog(@"do----%@", [NSThread currentThread]);
        }];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [thread executeTask:^{
                NSLog(@"do111----%@", [NSThread currentThread]);
            }];
        });
    }
}

- (void)test_group
{
    [NSGCDGroup setup_group_async];
}

- (void)test_condLock
{
    ZYConditionLockTest *condTest = [ZYConditionLockTest new];
    [condTest setup];
}

- (void)test_rwLock
{
    ZYRWLock *rwLock = [ZYRWLock new];
    [rwLock setup];
}

- (void)test_gcdBarrier
{
    ZYGcdBarrierTest *barrierTest = [ZYGcdBarrierTest new];
    [barrierTest setup];
}

- (void)test_displayLink
{
    ZYTimerTest *timer = [ZYTimerTest new];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"%@", timer);
    });
}

- (void)test_gcdTimer
{
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    //设置时间
    int start = 2.0;  //2s后开始执行
    int interval = 1.0;  //1s执行一次
    dispatch_source_set_timer(timer,
                              dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC),
                              interval * NSEC_PER_SEC,
                              0);
    
    //执行block回调
//    dispatch_source_set_event_handler(timer, ^{
//        NSLog(@"timer------");
//    });
    
    dispatch_source_set_event_handler_f(timer, updateTimer);
    
    dispatch_resume(timer);
    self.timer = timer;
}



void updateTimer(void *params)
{
    NSLog(@"updateTimer--------");
}

- (void)updateTimer111
{
    NSLog(@"updateTimer11111--------:: %@", [NSThread currentThread]);
}

- (void)test_gcdTimer1111
{
    ZYTimerTask *task = [ZYGCDTimer scheduleTimerWithTarget:self selector:@selector(updateTimer111) delay:0 interval:1 repeat:YES isMainThread:NO];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [ZYGCDTimer cancelTask:task];
    });
}

- (void)viewDidLoad {
    [super viewDidLoad];
    {
        ZYTestView *view = [[ZYTestView alloc] init];
        [self.view addSubview:view];
        [view removeFromSuperview];
        NSLog(@"--------------------------------");
    }
    NSLog(@"++++++++++++++++++++++++++++");
    
    int x = add(100, 200);
    int y = sub(900, 200);
    
    NSLog(@"%d %d", x, y);
}


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
}


@end
